using System;
using System.Collections.Generic;
using System.Diagnostics;
using NUnit.Framework;
using wpffc.contracts.domaindata;
using wpffc.contracts.infrastructure;
using wpffc.flashcardbox.domaindata;

namespace wpffc.flashcardbox.tests
{
    [TestFixture]
    public class test_Advance_card
    {
        [Test]
        public void Pass_on_flashcardbox()
        {
            var box = new FlashCardBox(1, 2, new int[0]);
            box.Batch.Enqueue(new BatchCard { Card = new Card { Question = "q1" } });

            var sut = new Advance_card();
            IFlashCardBox boxPassedOn = null;
            sut.Continue += _ => boxPassedOn = _;
            sut.Inject(new SharedState<IFlashCardBox> { Value = box });

            sut.Process(true);

            Assert.AreSame(box, boxPassedOn);
        }


        [Test]
        public void Move_to_next_compartment_if_answer_known()
        {
            var box = new FlashCardBox(1,2,new[]{0, 1});
            box.Batch.Enqueue(new BatchCard { CompartmentIndex = 0, Card = new Card { Question = "q1" } });
            box.Batch.Enqueue(new BatchCard { Card = new Card { Question = "q2" } });

            var sut = new Advance_card();
            sut.Continue += _ => { };
            sut.Inject(new SharedState<IFlashCardBox> { Value = box });

            sut.Process(true);

            Assert.AreEqual(BatchStatus.NeedsRefill, box.Batch.Status);
            Assert.AreEqual("q2", box.Batch.Peek().Card.Question);
            Assert.AreEqual("q1", box.Compartments[1].Dequeue().Question);
        }


        [Test]
        public void Move_to_archive_if_answer_known_on_card_from_last_compartment()
        {
            var box = new FlashCardBox(1, 2, new[] { 0 });
            box.Batch.Enqueue(new BatchCard { CompartmentIndex = 0, Card = new Card { Question = "q1" } });
            box.Batch.Enqueue(new BatchCard { Card = new Card { Question = "q2" } });

            var sut = new Advance_card();
            sut.Continue += _ => { };
            sut.Inject(new SharedState<IFlashCardBox> { Value = box });

            sut.Process(true);

            Assert.AreEqual(BatchStatus.NeedsRefill, box.Batch.Status);
            Assert.AreEqual("q2", box.Batch.Peek().Card.Question);
            Assert.AreEqual("q1", box.Archive.Dequeue().Question);
        }


        [Test]
        public void Requeue_card_if_answer_not_known()
        {
            var box = new FlashCardBox(1, 2, new int[0]);
            box.Batch.Enqueue(new BatchCard { Card = new Card { Question = "q1" } });
            box.Batch.Enqueue(new BatchCard { Card = new Card { Question = "q2" } });

            var sut = new Advance_card();
            sut.Continue += _ => { };
            sut.Inject(new SharedState<IFlashCardBox> { Value = box });

            sut.Process(false);

            Assert.AreEqual(BatchStatus.Full, box.Batch.Status);
            Assert.AreEqual("q2", box.Batch.Peek().Card.Question);
        }


        [Test]
        public void Just_continue_on_empty_batch()
        {
            var box = new FlashCardBox(1, 2, new int[0]);

            var sut = new Advance_card();
            var continued = false;
            sut.Continue += _ => { continued = true; };
            sut.Inject(new SharedState<IFlashCardBox> { Value = box });

            sut.Process(false);

            Assert.IsTrue(continued);
        }
    }
}